package com.lovezy.platform.wiki.service.impl;

import com.github.pagehelper.PageInfo;
import com.lovezy.platform.core.base.enums.StatusEnum;
import com.lovezy.platform.core.base.query.Pager;
import com.lovezy.platform.core.base.service.MapperService;
import com.lovezy.platform.core.utils.ArrayUtil;
import com.lovezy.platform.wiki.enums.TraitTypeEnum;
import com.lovezy.platform.wiki.form.GameInfoForm;
import com.lovezy.platform.wiki.mapper.GameTraitMapper;
import com.lovezy.platform.wiki.model.GameTrait;
import com.lovezy.platform.wiki.model.GameTraitExample;
import com.lovezy.platform.wiki.query.TraitQuery;
import com.lovezy.platform.wiki.service.GameTraitService;
import com.lovezy.platform.wiki.vo.WikiTraitVo;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static java.util.stream.Collectors.toList;

/**
 * 游戏特质服务
 * Created by jin on 2017/11/7.
 */
@Service
public class GameTraitServiceImpl extends MapperService<GameTrait,Integer,GameTraitMapper> implements GameTraitService{

    private final Object traitLock = new Object();

    @Override
    public List<GameTrait> saveGameTrait(GameInfoForm form) {
        List<GameTrait> traits = new ArrayList<>();
        List<String> categories = form.getCategories();
        List<String> mechanisms = form.getMechanisms();
        Date now = new Date();
        if (!ArrayUtil.isEmpty(categories)) {
            List<GameTrait> categorieTraits = categories.stream().map(v -> {
                GameTrait trait = new GameTrait();
                trait.setName(v);
                trait.setType(TraitTypeEnum.CATEGORIE.value());
                trait.setStatus(StatusEnum.NORMAL.value());
                trait.setGmtCreate(now);
                trait.setGmtModify(now);
                return trait;
            }).collect(toList());
            traits.addAll(categorieTraits);
        }

        if (!ArrayUtil.isEmpty(mechanisms)) {
            List<GameTrait> mechanismTraits = mechanisms.stream().map(name -> {
                GameTrait trait = new GameTrait();
                trait.setName(name);
                trait.setType(TraitTypeEnum.MECHANISM.value());
                trait.setStatus(StatusEnum.NORMAL.value());
                trait.setGmtCreate(now);
                trait.setGmtModify(now);
                return trait;
            }).collect(toList());
            traits.addAll(mechanismTraits);
        }

        traits.forEach(this::saveTraits);
        return traits;
    }

    @Override
    public GameTrait selectById(@NotNull Integer traitId) {
        return mapper.selectByPrimaryKey(traitId);
    }

    @Override
    public PageInfo<WikiTraitVo> traitList(TraitQuery query) {
        return Pager.doPageInfo(query, () -> mapper.traitList(query));
    }

    private void saveTraits(GameTrait trait) {
        Byte traitType = trait.getType();
        String name = trait.getName();
        GameTraitExample example = new GameTraitExample();
        example.createCriteria()
                .andTypeEqualTo(traitType)
                .andNameEqualTo(name)
                .andStatusEqualTo(StatusEnum.NORMAL.value());
        Optional<GameTrait> traitOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
        if(!traitOptional.isPresent()){
            synchronized (traitLock) {
                Optional<GameTrait> anotherOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
                if (!anotherOptional.isPresent()) {
                    mapper.insert(trait);
                }
            }
        }
    }

}
